home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / tcsh.4.3 / part01 next >
Encoding:
Internet Message Format  |  1987-09-27  |  59.0 KB

  1. Subject:  v11i084:  Tcsh for 4.3 CSH, Part01/02
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: chris@nrcvax.uucp (Chris Grevstad)
  7. Posting-number: Volume 11, Issue 84
  8. Archive-name: tcsh.4.3/part01
  9.  
  10. This stuff is to adapt Paul Placeway's tcsh to BSD4.3 csh.
  11.  
  12. The files tcsh.DIFF* are to replace the DIFFS* files that got distributed
  13. with the tcsh stuff in volume 10 of comp.sources.unix.
  14.  
  15. Be sure to replace DIFFS.1 with tcsh.DIFFS.1 and DIFFS.2 with tcsh.DIFFS.2.
  16. At that point you should be able to follow the directions included in the
  17. README file.
  18.  
  19.     Chris Grevstad
  20.     chris@nrcvax.UUCP
  21.     ..!ihnp4!nrcvax!chris
  22.     chris@trwind.trw.com
  23.  
  24. #! /bin/sh
  25. # This is a shell archive, meaning:
  26. # 1. Remove everything above the #! /bin/sh line.
  27. # 2. Save the resulting text in a file.
  28. # 3. Execute the file with /bin/sh (not csh) to create:
  29. #    DIFFS.1
  30. # This archive created: Thu Sep 24 16:28:11 1987
  31. export PATH; PATH=/bin:/usr/bin:$PATH
  32. if test -f 'DIFFS.1'
  33. then
  34.     echo shar: "will not over-write existing file 'DIFFS.1'"
  35. else
  36. cat << \SHAR_EOF > 'DIFFS.1'
  37. *** sh.c    Sat Mar 29 07:17:01 1986
  38. --- /usr/src/local/tcsh/sh.c    Thu Sep 17 23:22:08 1987
  39. ***************
  40. *** 7,12
  41.   #ifndef lint
  42.   static char *sccsid = "@(#)sh.c    5.3 (Berkeley) 3/29/86";
  43.   #endif
  44.   
  45.   #include "sh.h"
  46.   #include <sys/ioctl.h>
  47.  
  48. --- 7,13 -----
  49.   #ifndef lint
  50.   static char *sccsid = "@(#)sh.c    5.3 (Berkeley) 3/29/86";
  51.   #endif
  52. + static char *Version = "tcsh 5.4 (Ohio State) 7/18/87 Patch level 0";
  53.   
  54.   #include "sh.h"
  55.   /* #include <sys/ioctl.h> */
  56. ***************
  57. *** 9,15
  58.   #endif
  59.   
  60.   #include "sh.h"
  61. ! #include <sys/ioctl.h>
  62.   /*
  63.    * C Shell
  64.    *
  65.  
  66. --- 10,27 -----
  67.   static char *Version = "tcsh 5.4 (Ohio State) 7/18/87 Patch level 0";
  68.   
  69.   #include "sh.h"
  70. ! /* #include <sys/ioctl.h> */
  71. ! #ifdef SVID
  72. ! struct termio termiob;
  73. ! # ifdef OREO
  74. ! struct ltchars ltcbuf;
  75. ! #include <compat.h>
  76. ! # endif OREO
  77. ! #endif SVID
  78.   /*
  79.    * C Shell
  80.    *
  81. ***************
  82. *** 18,23
  83.    *
  84.    * Jim Kulp, IIASA, Laxenburg, Austria
  85.    * April 1980
  86.    */
  87.   
  88.   char    *pathlist[] =    { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
  89.  
  90. --- 30,55 -----
  91.    *
  92.    * Jim Kulp, IIASA, Laxenburg, Austria
  93.    * April 1980
  94. +  *
  95. +  * Filename recognition added:
  96. +  * Ken Greer, Ind. Consultant, Palo Alto CA
  97. +  * October 1983.
  98. +  *
  99. +  * Karl Kleinpaste, Computer Consoles, Inc.
  100. +  * Added precmd, periodic/tperiod, prompt changes,
  101. +  * directory stack hack, and login watch.
  102. +  * Sometime March 1983 - Feb 1984.
  103. +  *
  104. +  * Added scheduled commands, including the "sched" command,
  105. +  * plus the call to sched_run near the precmd et al
  106. +  * routines.
  107. +  * Upgraded scheduled events for running events while
  108. +  * sitting idle at command input.
  109. +  *
  110. +  * Paul Placeway, Ohio State
  111. +  * added stuff for running with twenex/inputl  9 Oct 1984.
  112. +  *
  113. +  * ported to Apple Unix (TM) (OREO)  26 -- 29 Jun 1987
  114.    */
  115.   
  116.   char    *pathlist[] =    { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
  117. ***************
  118. *** 23,30
  119.   char    *pathlist[] =    { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
  120.   char    *dumphist[] =    { "history", "-h", 0, 0 };
  121.   char    *loadhist[] =    { "source", "-h", "~/.history", 0 };
  122. ! char    HIST = '!';
  123. ! char    HISTSUB = '^';
  124.   bool    nofile;
  125.   bool    reenter;
  126.   bool    nverbose;
  127.  
  128. --- 55,62 -----
  129.   char    *pathlist[] =    { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
  130.   char    *dumphist[] =    { "history", "-h", 0, 0 };
  131.   char    *loadhist[] =    { "source", "-h", "~/.history", 0 };
  132. ! /* char    HIST = '!'; */
  133. ! /* char    HISTSUB = '^'; */
  134.   bool    nofile;
  135.   bool    reenter;
  136.   bool    nverbose;
  137. ***************
  138. *** 34,39
  139.   bool    batch;
  140.   bool    prompt = 1;
  141.   bool    enterhist = 0;
  142.   
  143.   extern    gid_t getegid(), getgid();
  144.   extern    uid_t geteuid(), getuid();
  145.  
  146. --- 66,79 -----
  147.   bool    batch;
  148.   bool    prompt = 1;
  149.   bool    enterhist = 0;
  150. + bool    tellwhat = 0;
  151. + int    phup();
  152. + time_t    t_period;
  153. + time_t    watch_period = 0;
  154. + struct who *wholist;
  155. + bool    precmd_active = 0;
  156. + bool    periodic_active = 0;
  157. + char    buff[128];        /* for gethostname(2), and printprompt() */
  158.   
  159.   extern    gid_t getegid(), getgid();
  160.   extern    uid_t geteuid(), getuid();
  161. ***************
  162. *** 38,43
  163.   extern    gid_t getegid(), getgid();
  164.   extern    uid_t geteuid(), getuid();
  165.   
  166.   main(c, av)
  167.       int c;
  168.       char **av;
  169.  
  170. --- 78,111 -----
  171.   extern    gid_t getegid(), getgid();
  172.   extern    uid_t geteuid(), getuid();
  173.   
  174. + #define DEFAULT_AUTOLOGOUT    "60"    /* 1 Hour Alarm default */
  175. + auto_logout ()
  176. + {
  177. +     printf ("auto-logout\n");
  178. +     close (SHIN);
  179. +     set ("logout", "automatic");
  180. +     child++;
  181. +     goodbye ();
  182. + }
  183. + alrmcatch ()
  184. + {
  185. +     extern    struct    sched_event *sched_ptr;
  186. +     time_t    cl;
  187. +     if (!sched_ptr)
  188. +         auto_logout();    /* no other possibility - logout */
  189. +     time(&cl);
  190. +     if (sched_ptr->t_when <= cl + 1)
  191. +         sched_run();
  192. +     else
  193. +         auto_logout();
  194. +     setalarm();
  195. + }
  196. + char    *ttyname();
  197.   main(c, av)
  198.       int c;
  199.       char **av;
  200. ***************
  201. *** 47,52
  202.       struct sigvec osv;
  203.   
  204.       settimes();            /* Immed. estab. timing base */
  205.       v = av;
  206.       if (eq(v[0], "a.out"))        /* A.out's are quittable */
  207.           quitit = 1;
  208.  
  209. --- 115,128 -----
  210.       struct sigvec osv;
  211.   
  212.       settimes();            /* Immed. estab. timing base */
  213. + #ifdef OREO
  214. +     set42sig();
  215. +     setcompat (COMPAT_BSDPROT | COMPAT_BSDNBIO | COMPAT_BSDSIGNALS |
  216. +           COMPAT_SYSCALLS);
  217. + #endif
  218. +     HIST = '!';
  219. +     HISTSUB = '^';
  220.       v = av;
  221.       if (eq(v[0], "a.out"))        /* A.out's are quittable */
  222.           quitit = 1;
  223. ***************
  224. *** 56,61
  225.           (void) time(&chktim);
  226.   
  227.       /*
  228.        * Move the descriptors to safe places.
  229.        * The variable didfds is 0 while we have only FSH* to work with.
  230.        * When didfds is true, we have 0,1,2 and prefer to use these.
  231.  
  232. --- 132,144 -----
  233.           (void) time(&chktim);
  234.   
  235.       /*
  236. +      * Initialize for periodic command intervals.
  237. +      * Also, initialize the dummy tty list for login-watch.
  238. +      */
  239. +     time(&t_period);
  240. +     initwatch();
  241. +     /*
  242.        * Move the descriptors to safe places.
  243.        * The variable didfds is 0 while we have only FSH* to work with.
  244.        * When didfds is true, we have 0,1,2 and prefer to use these.
  245. ***************
  246. *** 69,74
  247.        * CHILD is munged when forking/waiting
  248.        */
  249.   
  250.       set("status", "0");
  251.       dinit(cp = getenv("HOME"));    /* dinit thinks that HOME == cwd in a
  252.                        * login shell */
  253.  
  254. --- 152,181 -----
  255.        * CHILD is munged when forking/waiting
  256.        */
  257.   
  258. +     /* 7-10-87 Paul Placeway
  259. +      * autologout should be set ONLY on login shells and on shells
  260. +      * running as root.  Out of these, autologout should NOT be set
  261. +      * for any psudo-terminals (this catches most window systems)
  262. +      * and not for any terminal running X windows.
  263. +      *
  264. +      * At Ohio State, we have had problems with a user having his
  265. +      * X session drop out from under him (on a Sun) because the shell
  266. +      * in his master xterm timed out and exited.
  267. +      *
  268. +      * Really, this should be done with a program external to the
  269. +      * shell, that watches for no activity (and NO running programs,
  270. +      * such as dump) on a terminal for a long peroid of time, and
  271. +      * then SIGHUPS the shell on that terminal.
  272. +      */
  273. +     if (loginsh || getuid() == 0) { /* only for login shells or root */
  274. +         cp = ttyname(SHIN);
  275. +         if ((strncmp (cp, "ttyp", 4) != 0) &&
  276. +         (strncmp (cp, "ttyp", 4) != 0))
  277. +         if (getenv("DISPLAY") == NOSTR) /* NOT on X window shells */
  278. +             set("autologout", DEFAULT_AUTOLOGOUT);
  279. +     }
  280. +     signal(SIGALRM, alrmcatch);
  281.       set("status", "0");
  282.       set("tcsh", "1");        /* so I can tell the difference */
  283.       dinit(cp = getenv("HOME"));    /* dinit thinks that HOME == cwd in a
  284. ***************
  285. *** 70,75
  286.        */
  287.   
  288.       set("status", "0");
  289.       dinit(cp = getenv("HOME"));    /* dinit thinks that HOME == cwd in a
  290.                        * login shell */
  291.       if (cp == NOSTR)
  292.  
  293. --- 177,183 -----
  294.   
  295.       signal(SIGALRM, alrmcatch);
  296.       set("status", "0");
  297. +     set("tcsh", "1");        /* so I can tell the difference */
  298.       dinit(cp = getenv("HOME"));    /* dinit thinks that HOME == cwd in a
  299.                        * login shell */
  300.       if (cp == NOSTR)
  301. ***************
  302. *** 84,89
  303.           set("user", savestr(cp));
  304.       if ((cp = getenv("TERM")) != NOSTR)
  305.           set("term", savestr(cp));
  306.       /*
  307.        * Re-initialize path if set in environment
  308.        */
  309.  
  310. --- 192,199 -----
  311.           set("user", savestr(cp));
  312.       if ((cp = getenv("TERM")) != NOSTR)
  313.           set("term", savestr(cp));
  314. +     set ("version", Version); /* publish the shell version */
  315.       /*
  316.        * set usefull environment things for the user
  317.        */
  318. ***************
  319. *** 85,90
  320.       if ((cp = getenv("TERM")) != NOSTR)
  321.           set("term", savestr(cp));
  322.       /*
  323.        * Re-initialize path if set in environment
  324.        */
  325.       if ((cp = getenv("PATH")) == NOSTR)
  326.  
  327. --- 195,235 -----
  328.   
  329.       set ("version", Version); /* publish the shell version */
  330.       /*
  331. +      * set usefull environment things for the user
  332. +      */
  333. +     itoa (getuid(), buff);
  334. +     set ("uid", buff);
  335. +     if ((cp = getenv("HOST")) == NOSTR) { /* if not allready set */
  336. +         gethostname (buff, sizeof(buff));
  337. +         buff[sizeof(buff) -1] = '\0'; /* just in case */
  338. +         setenv ("HOST", buff);
  339. +     }
  340. +     if ((cp = getenv("HOSTTYPE")) == NOSTR) { /* if not allready set */
  341. + #ifdef vax
  342. +         setenv ("HOSTTYPE", "vax");
  343. + #endif
  344. + #ifdef sun
  345. + # ifdef mc68010
  346. +         setenv ("HOSTTYPE", "sun2");
  347. + # else
  348. + #  ifdef mc68020
  349. +         setenv ("HOSTTYPE", "sun3");
  350. + #  else
  351. +         setenv ("HOSTTYPE", "sun");
  352. + #  endif
  353. + # endif
  354. + #endif
  355. + #ifdef pyr            /* pyramid */
  356. +         setenv ("HOSTTYPE", "pyramid");
  357. + #endif
  358. + #ifdef OREO
  359. +         setenv ("HOSTTYPE", "mac2");
  360. + #endif OREO
  361. + #ifdef ns32000                  /* ugh!  This should change */
  362. +             setenv ("HOSTTYPE", "multimax");
  363. + #endif
  364. +     }
  365. +     /*
  366.        * Re-initialize path if set in environment
  367.        */
  368.       if ((cp = getenv("PATH")) == NOSTR)
  369. ***************
  370. *** 205,210
  371.           }
  372.           file = v[0];
  373.           SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
  374.           (void) ioctl(SHIN, FIOCLEX, (char *)0);
  375.           prompt = 0;
  376.           c--, v++;
  377.  
  378. --- 350,356 -----
  379.           }
  380.           file = v[0];
  381.           SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
  382. + #ifdef BSD4_3
  383.           (void) ioctl(SHIN, FIOCLEX, (char *)0);
  384.   #endif
  385.           prompt = 0;
  386. ***************
  387. *** 206,211
  388.           file = v[0];
  389.           SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
  390.           (void) ioctl(SHIN, FIOCLEX, (char *)0);
  391.           prompt = 0;
  392.           c--, v++;
  393.       }
  394.  
  395. --- 352,358 -----
  396.           SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
  397.   #ifdef BSD4_3
  398.           (void) ioctl(SHIN, FIOCLEX, (char *)0);
  399. + #endif
  400.           prompt = 0;
  401.           c--, v++;
  402.       }
  403. ***************
  404. *** 239,246
  405.       /*
  406.        * Set up the prompt.
  407.        */
  408. !     if (prompt)
  409. !         set("prompt", uid == 0 ? "# " : "% ");
  410.   
  411.       /*
  412.        * If we are an interactive shell, then start fiddling
  413.  
  414. --- 386,395 -----
  415.       /*
  416.        * Set up the prompt.
  417.        */
  418. !     if (prompt) {
  419. !         set("prompt", uid == 0 ? "# " : "> ");
  420. !         set("prompt2", "\277 "); /* that's a meta-questionmark */
  421. !     }
  422.   
  423.       /*
  424.        * If we are an interactive shell, then start fiddling
  425. ***************
  426. *** 275,280
  427.               else
  428.                   f = -1;
  429.   retry:
  430.               if (ioctl(f, TIOCGPGRP, (char *)&tpgrp) == 0 &&
  431.                   tpgrp != -1) {
  432.                   int ldisc;
  433.  
  434. --- 424,430 -----
  435.               else
  436.                   f = -1;
  437.   retry:
  438. + #ifdef BSDJOBS            /* if we have tty job control */
  439.               if (ioctl(f, TIOCGPGRP, (char *)&tpgrp) == 0 &&
  440.                   tpgrp != -1) {
  441.                   int ldisc;
  442. ***************
  443. *** 286,291
  444.                   }
  445.                   if (ioctl(f, TIOCGETD, (char *)&oldisc) != 0) 
  446.                       goto notty;
  447.                   if (oldisc != NTTYDISC) {
  448.   #ifdef DEBUG
  449.                       printf("Switching to new tty driver...\n");
  450.  
  451. --- 436,468 -----
  452.                   }
  453.                   if (ioctl(f, TIOCGETD, (char *)&oldisc) != 0) 
  454.                       goto notty;
  455. + # ifdef OREO
  456. +             if (ioctl(f, TCGETA, &termiob) != 0)
  457. +                     goto notty;
  458. +                 if ((getcompat(COMPAT_BSDTTY) & COMPAT_BSDTTY)
  459. +                     != COMPAT_BSDTTY) {
  460. + #  ifdef DEBUG
  461. +                     printf("Switching to new tty driver...\n");
  462. + #  endif DEBUG
  463. +                     setcompat(COMPAT_BSDTTY);
  464. +                     if (ioctl (f, TIOCGLTC, <cbuf) < 0) {
  465. +                     printf ("Couldn't get local chars.\n");
  466. +                     } else {
  467. + #  ifdef DEBUG
  468. +                     printf ("Setting ^Z, etc....\n");
  469. + #  endif DEBUG
  470. +                     ltcbuf.t_suspc = '\032'; /* ^Z */
  471. +                     ltcbuf.t_dsuspc = '\031'; /* ^Y */
  472. +                     ltcbuf.t_rprntc = '\022'; /* ^R */
  473. +                     ltcbuf.t_flushc = '\017'; /* ^O */
  474. +                     ltcbuf.t_werasc = '\027'; /* ^W */
  475. +                     ltcbuf.t_lnextc = '\026'; /* ^V */
  476. +                     ioctl (f, TIOCSLTC, <cbuf);
  477. +                     }
  478. +                     termiob.c_cc[VSWTCH] = '\0';
  479. +                     ioctl(f, TCSETAF, &termiob);
  480. +                 }
  481. + # else OREO
  482.                   if (oldisc != NTTYDISC) {
  483.   #  ifdef DEBUG
  484.                       printf("Switching to new tty driver...\n");
  485. ***************
  486. *** 287,293
  487.                   if (ioctl(f, TIOCGETD, (char *)&oldisc) != 0) 
  488.                       goto notty;
  489.                   if (oldisc != NTTYDISC) {
  490. ! #ifdef DEBUG
  491.                       printf("Switching to new tty driver...\n");
  492.   #endif DEBUG
  493.                       ldisc = NTTYDISC;
  494.  
  495. --- 464,470 -----
  496.                   }
  497.   # else OREO
  498.                   if (oldisc != NTTYDISC) {
  499. ! #  ifdef DEBUG
  500.                       printf("Switching to new tty driver...\n");
  501.   #  endif DEBUG
  502.                       ldisc = NTTYDISC;
  503. ***************
  504. *** 289,295
  505.                   if (oldisc != NTTYDISC) {
  506.   #ifdef DEBUG
  507.                       printf("Switching to new tty driver...\n");
  508. ! #endif DEBUG
  509.                       ldisc = NTTYDISC;
  510.                       (void) ioctl(f, TIOCSETD,
  511.                           (char *)&ldisc);
  512.  
  513. --- 466,472 -----
  514.                   if (oldisc != NTTYDISC) {
  515.   #  ifdef DEBUG
  516.                       printf("Switching to new tty driver...\n");
  517. ! #  endif DEBUG
  518.                       ldisc = NTTYDISC;
  519.                       (void) ioctl(f, TIOCSETD,
  520.                           (char *)&ldisc);
  521. ***************
  522. *** 295,300
  523.                           (char *)&ldisc);
  524.                   } else
  525.                       oldisc = -1;
  526.                   opgrp = shpgrp;
  527.                   shpgrp = getpid();
  528.                   tpgrp = shpgrp;
  529.  
  530. --- 472,478 -----
  531.                           (char *)&ldisc);
  532.                   } else
  533.                       oldisc = -1;
  534. + # endif OREO
  535.                   opgrp = shpgrp;
  536.                   shpgrp = getpid();
  537.                   tpgrp = shpgrp;
  538. ***************
  539. *** 307,312
  540.     printf("Warning: no access to tty; thus no job control in this shell...\n");
  541.                   tpgrp = -1;
  542.               }
  543.           }
  544.       }
  545.       if (setintr == 0 && parintr == SIG_DFL)
  546.  
  547. --- 485,494 -----
  548.     printf("Warning: no access to tty; thus no job control in this shell...\n");
  549.                   tpgrp = -1;
  550.               }
  551. + #else BSDJOBS            /* don't have job control, so frotz it */
  552. +             tpgrp = -1;
  553. +             printf ("Warning: jobs not implemented yet.\n");
  554. + #endif BSDJOBS
  555.           }
  556.       }
  557.       if (setintr == 0 && parintr == SIG_DFL)
  558. ***************
  559. *** 321,326
  560.       haderr = 0;        /* In case second time through */
  561.       if (!fast && reenter == 0) {
  562.           reenter++;
  563.           /* Will have value("home") here because set fast if don't */
  564.           srccat(value("home"), "/.cshrc");
  565.           if (!fast && !arginp && !onelflg && !havhash)
  566.  
  567. --- 503,512 -----
  568.       haderr = 0;        /* In case second time through */
  569.       if (!fast && reenter == 0) {
  570.           reenter++;
  571. +                 if (!fast && !arginp && !onelflg) { /* PWP setup stuff */
  572. +             ed_Init();    /* init the new line editor */
  573. +             /* PWP: setup the editor BEFORE doing .cshrc, else bugs! */
  574. +         }    
  575.           /* Will have value("home") here because set fast if don't */
  576.           srccat(value("home"), "/.cshrc");    /* upward compat. */
  577.           if (!fast && !arginp && !onelflg && !havhash)
  578. ***************
  579. *** 322,328
  580.       if (!fast && reenter == 0) {
  581.           reenter++;
  582.           /* Will have value("home") here because set fast if don't */
  583. !         srccat(value("home"), "/.cshrc");
  584.           if (!fast && !arginp && !onelflg && !havhash)
  585.               dohash();
  586.           if (loginsh) {
  587.  
  588. --- 508,514 -----
  589.               /* PWP: setup the editor BEFORE doing .cshrc, else bugs! */
  590.           }    
  591.           /* Will have value("home") here because set fast if don't */
  592. !         srccat(value("home"), "/.cshrc");    /* upward compat. */
  593.           if (!fast && !arginp && !onelflg && !havhash)
  594.               dohash();
  595.           if (loginsh) {
  596. ***************
  597. *** 350,360
  598.       /*
  599.        * Mop-up.
  600.        */
  601. !     if (loginsh) {
  602. !         printf("logout\n");
  603. !         (void) close(SHIN);
  604. !         child++;
  605. !         goodbye();
  606.       }
  607.       rechist();
  608.       exitstat();
  609.  
  610. --- 536,550 -----
  611.       /*
  612.        * Mop-up.
  613.        */
  614. !     if (intty) {
  615. !         if (loginsh) {
  616. !             printf("logout\n");
  617. !             (void) close(SHIN);
  618. !             child++;
  619. !             goodbye();
  620. !         } else {
  621. !             printf ("exit\n");
  622. !         }
  623.       }
  624.       rechist();
  625.       exitstat();
  626. ***************
  627. *** 362,368
  628.   
  629.   untty()
  630.   {
  631.       if (tpgrp > 0) {
  632.           (void) setpgrp(0, opgrp);
  633.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  634.  
  635. --- 552,558 -----
  636.   
  637.   untty()
  638.   {
  639. ! #ifdef BSDJOBS
  640.       if (tpgrp > 0) {
  641.           (void) setpgrp(0, opgrp);
  642.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  643. ***************
  644. *** 366,371
  645.       if (tpgrp > 0) {
  646.           (void) setpgrp(0, opgrp);
  647.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  648.           if (oldisc != -1 && oldisc != NTTYDISC) {
  649.   #ifdef DEBUG
  650.               printf("\nReverting to old tty driver...\n");
  651.  
  652. --- 556,562 -----
  653.       if (tpgrp > 0) {
  654.           (void) setpgrp(0, opgrp);
  655.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  656. + # ifndef OREO
  657.           if (oldisc != -1 && oldisc != NTTYDISC) {
  658.   #  ifdef DEBUG
  659.               printf("\nReverting to old tty driver...\n");
  660. ***************
  661. *** 367,373
  662.           (void) setpgrp(0, opgrp);
  663.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  664.           if (oldisc != -1 && oldisc != NTTYDISC) {
  665. ! #ifdef DEBUG
  666.               printf("\nReverting to old tty driver...\n");
  667.   #endif DEBUG
  668.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  669.  
  670. --- 558,564 -----
  671.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
  672.   # ifndef OREO
  673.           if (oldisc != -1 && oldisc != NTTYDISC) {
  674. ! #  ifdef DEBUG
  675.               printf("\nReverting to old tty driver...\n");
  676.   #  endif DEBUG
  677.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  678. ***************
  679. *** 369,375
  680.           if (oldisc != -1 && oldisc != NTTYDISC) {
  681.   #ifdef DEBUG
  682.               printf("\nReverting to old tty driver...\n");
  683. ! #endif DEBUG
  684.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  685.           }
  686.       }
  687.  
  688. --- 560,566 -----
  689.           if (oldisc != -1 && oldisc != NTTYDISC) {
  690.   #  ifdef DEBUG
  691.               printf("\nReverting to old tty driver...\n");
  692. ! #  endif DEBUG
  693.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  694.           }
  695.   # endif OREO
  696. ***************
  697. *** 372,377
  698.   #endif DEBUG
  699.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  700.           }
  701.       }
  702.   }
  703.   
  704.  
  705. --- 563,569 -----
  706.   #  endif DEBUG
  707.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  708.           }
  709. + # endif OREO
  710.       }
  711.   #endif BSDJOBS
  712.   }
  713. ***************
  714. *** 373,378
  715.               (void) ioctl(FSHTTY, TIOCSETD, (char *)&oldisc);
  716.           }
  717.       }
  718.   }
  719.   
  720.   importpath(cp)
  721.  
  722. --- 565,571 -----
  723.           }
  724.   # endif OREO
  725.       }
  726. + #endif BSDJOBS
  727.   }
  728.   
  729.   importpath(cp)
  730. ***************
  731. *** 421,426
  732.       register char *ep = strspl(cp, dp);
  733.       register int unit = dmove(open(ep, 0), -1);
  734.   
  735.       (void) ioctl(unit, FIOCLEX, (char *)0);
  736.       xfree(ep);
  737.   #ifdef INGRES
  738.  
  739. --- 614,620 -----
  740.       register char *ep = strspl(cp, dp);
  741.       register int unit = dmove(open(ep, 0), -1);
  742.   
  743. + #ifdef BSD4_3
  744.       (void) ioctl(unit, FIOCLEX, (char *)0);
  745.   #endif
  746.       xfree(ep);
  747. ***************
  748. *** 422,427
  749.       register int unit = dmove(open(ep, 0), -1);
  750.   
  751.       (void) ioctl(unit, FIOCLEX, (char *)0);
  752.       xfree(ep);
  753.   #ifdef INGRES
  754.       srcunit(unit, 0, 0);
  755.  
  756. --- 616,622 -----
  757.   
  758.   #ifdef BSD4_3
  759.       (void) ioctl(unit, FIOCLEX, (char *)0);
  760. + #endif
  761.       xfree(ep);
  762.   #ifdef INGRES
  763.       srcunit(unit, 0, 0);
  764. ***************
  765. *** 464,471
  766.       if (onlyown) {
  767.           struct stat stb;
  768.   
  769. !         if (fstat(unit, &stb) < 0 ||
  770. !             (stb.st_uid != uid && stb.st_gid != getgid())) {
  771.               (void) close(unit);
  772.               return;
  773.           }
  774.  
  775. --- 659,667 -----
  776.       if (onlyown) {
  777.           struct stat stb;
  778.   
  779. !         if (fstat(unit, &stb) < 0
  780. !         /*    || (stb.st_uid != uid && stb.st_gid != getgid()) */
  781. !             ) {
  782.               (void) close(unit);
  783.               return;
  784.           }
  785. ***************
  786. *** 573,578
  787.   
  788.   goodbye()
  789.   {
  790.       if (loginsh) {
  791.           (void) signal(SIGQUIT, SIG_IGN);
  792.           (void) signal(SIGINT, SIG_IGN);
  793.  
  794. --- 769,775 -----
  795.   
  796.   goodbye()
  797.   {
  798. +     rechist();
  799.       if (loginsh) {
  800.           (void) signal(SIGQUIT, SIG_IGN);
  801.           (void) signal(SIGINT, SIG_IGN);
  802. ***************
  803. *** 578,583
  804.           (void) signal(SIGINT, SIG_IGN);
  805.           (void) signal(SIGTERM, SIG_IGN);
  806.           setintr = 0;        /* No interrupts after "logout" */
  807.           if (adrof("home"))
  808.               srccat(value("home"), "/.logout");
  809.       }
  810.  
  811. --- 775,782 -----
  812.           (void) signal(SIGINT, SIG_IGN);
  813.           (void) signal(SIGTERM, SIG_IGN);
  814.           setintr = 0;        /* No interrupts after "logout" */
  815. +         if (!(adrof("logout")))
  816. +             set ("logout", "normal");
  817.           if (adrof("home"))
  818.               srccat(value("home"), "/.logout");
  819.       }
  820. ***************
  821. *** 581,587
  822.           if (adrof("home"))
  823.               srccat(value("home"), "/.logout");
  824.       }
  825. -     rechist();
  826.       exitstat();
  827.   }
  828.   
  829.  
  830. --- 780,785 -----
  831.           if (adrof("home"))
  832.               srccat(value("home"), "/.logout");
  833.       }
  834.       exitstat();
  835.   }
  836.   
  837. ***************
  838. *** 654,661
  839.           if (v = gargv)
  840.               gargv = 0, blkfree(v);
  841.           reset();
  842. !     } else if (intty && wantnl)
  843. !         printf("\n");        /* Some like this, others don't */
  844.       error(NOSTR);
  845.   }
  846.   
  847.  
  848. --- 852,862 -----
  849.           if (v = gargv)
  850.               gargv = 0, blkfree(v);
  851.           reset();
  852. !     } else if (intty && wantnl) {
  853. !         /* printf("\n");    /* Some like this, others don't */
  854. !         putraw ('\r');
  855. !         putraw ('\n');
  856. !     }
  857.       error(NOSTR);
  858.   }
  859.   
  860. ***************
  861. *** 730,735
  862.           if (intty && prompt && evalvec == 0) {
  863.               mailchk();
  864.               /*
  865.                * If we are at the end of the input buffer
  866.                * then we are going to read fresh stuff.
  867.                * Otherwise, we are rereading input and don't
  868.  
  869. --- 931,946 -----
  870.           if (intty && prompt && evalvec == 0) {
  871.               mailchk();
  872.               /*
  873. +              * Watch for logins/logouts.
  874. +              * Next is scheduled commands stored previously using "sched."
  875. +              * Then execute periodic commands.
  876. +              * Following that, the prompt precmd is run.
  877. +              */
  878. +             watch_login();
  879. +             sched_run();
  880. +             period_cmd();
  881. +             precmd();
  882. +             /*
  883.                * If we are at the end of the input buffer
  884.                * then we are going to read fresh stuff.
  885.                * Otherwise, we are rereading input and don't
  886. ***************
  887. *** 737,742
  888.                */
  889.               if (fseekp == feobp)
  890.                   printprompt();
  891.           }
  892.           err = 0;
  893.   
  894.  
  895. --- 948,954 -----
  896.                */
  897.               if (fseekp == feobp)
  898.                   printprompt();
  899. +             setalarm();
  900.           }
  901.           err = 0;
  902.   
  903. ***************
  904. *** 744,750
  905.            * Echo not only on VERBOSE, but also with history expansion.
  906.            * If there is a lexical error then we forego history echo.
  907.            */
  908. !         if (lex(¶ml) && !err && intty ||
  909.               adrof("verbose")) {
  910.               haderr = 1;
  911.               prlex(¶ml);
  912.  
  913. --- 956,962 -----
  914.            * Echo not only on VERBOSE, but also with history expansion.
  915.            * If there is a lexical error then we forego history echo.
  916.            */
  917. !         if (lex(¶ml) && !err && intty && !tellwhat ||
  918.               adrof("verbose")) {
  919.               haderr = 1;
  920.               prlex(¶ml);
  921. ***************
  922. *** 750,755
  923.               prlex(¶ml);
  924.               haderr = 0;
  925.           }
  926.   
  927.           /*
  928.            * The parser may lose space if interrupted.
  929.  
  930. --- 962,968 -----
  931.               prlex(¶ml);
  932.               haderr = 0;
  933.           }
  934. +         alarm (0);                /* Autologout OFF */
  935.   
  936.           /*
  937.            * The parser may lose space if interrupted.
  938. ***************
  939. *** 763,769
  940.            * is from the terminal at the top level and not
  941.            * in a loop.
  942.            */
  943. !         if (enterhist || catch && intty && !whyles)
  944.               savehist(¶ml);
  945.   
  946.           /*
  947.  
  948. --- 976,982 -----
  949.            * is from the terminal at the top level and not
  950.            * in a loop.
  951.            */
  952. !         if (enterhist || catch && intty && !whyles && !tellwhat)
  953.               savehist(¶ml);
  954.   
  955.           /*
  956. ***************
  957. *** 783,788
  958.           alias(¶ml);
  959.   
  960.           /*
  961.            * Parse the words of the input into a parse tree.
  962.            */
  963.           t = syntax(paraml.next, ¶ml, 0);
  964.  
  965. --- 996,1009 -----
  966.           alias(¶ml);
  967.   
  968.           /*
  969. +          * If had a tell_what from twenex() then do
  970. +          */
  971. +         if (tellwhat) {
  972. +             tellmewhat(¶ml);
  973. +             reset();
  974. +         }
  975. +         /*
  976.            * Parse the words of the input into a parse tree.
  977.            */
  978.           t = syntax(paraml.next, ¶ml, 0);
  979. ***************
  980. *** 821,826
  981.       xfree(f);
  982.       if (u < 0 && !hflg)
  983.           Perror(f);
  984.       (void) ioctl(u, FIOCLEX, (char *)0);
  985.       srcunit(u, 0, hflg);
  986.   }
  987.  
  988. --- 1042,1048 -----
  989.       xfree(f);
  990.       if (u < 0 && !hflg)
  991.           Perror(f);
  992. + #ifdef BSD4_3
  993.       (void) ioctl(u, FIOCLEX, (char *)0);
  994.   #endif
  995.       srcunit(u, 0, hflg);
  996. ***************
  997. *** 822,827
  998.       if (u < 0 && !hflg)
  999.           Perror(f);
  1000.       (void) ioctl(u, FIOCLEX, (char *)0);
  1001.       srcunit(u, 0, hflg);
  1002.   }
  1003.   
  1004.  
  1005. --- 1044,1050 -----
  1006.           Perror(f);
  1007.   #ifdef BSD4_3
  1008.       (void) ioctl(u, FIOCLEX, (char *)0);
  1009. + #endif
  1010.       srcunit(u, 0, hflg);
  1011.   }
  1012.   
  1013. ***************
  1014. *** 870,876
  1015.       chktim = t;
  1016.   }
  1017.   
  1018. ! #include <pwd.h>
  1019.   /*
  1020.    * Extract a home directory from the password file
  1021.    * The argument points to a buffer where the name of the
  1022.  
  1023. --- 1093,1099 -----
  1024.       chktim = t;
  1025.   }
  1026.   
  1027. ! /* #include <pwd.h> */
  1028.   /*
  1029.    * Extract a home directory from the password file
  1030.    * The argument points to a buffer where the name of the
  1031. ***************
  1032. *** 896,901
  1033.   {
  1034.   
  1035.       didfds = 0;            /* 0, 1, 2 aren't set up */
  1036.       (void) ioctl(SHIN = dcopy(0, FSHIN), FIOCLEX, (char *)0);
  1037.       (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, (char *)0);
  1038.       (void) ioctl(SHDIAG = dcopy(2, FSHDIAG), FIOCLEX, (char *)0);
  1039.  
  1040. --- 1119,1125 -----
  1041.   {
  1042.   
  1043.       didfds = 0;            /* 0, 1, 2 aren't set up */
  1044. + #ifdef BSD4_3
  1045.       (void) ioctl(SHIN = dcopy(0, FSHIN), FIOCLEX, (char *)0);
  1046.       (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, (char *)0);
  1047.       (void) ioctl(SHDIAG = dcopy(2, FSHDIAG), FIOCLEX, (char *)0);
  1048. ***************
  1049. *** 900,905
  1050.       (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, (char *)0);
  1051.       (void) ioctl(SHDIAG = dcopy(2, FSHDIAG), FIOCLEX, (char *)0);
  1052.       (void) ioctl(OLDSTD = dcopy(SHIN, FOLDSTD), FIOCLEX, (char *)0);
  1053.       closem();
  1054.   }
  1055.   
  1056.  
  1057. --- 1124,1135 -----
  1058.       (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, (char *)0);
  1059.       (void) ioctl(SHDIAG = dcopy(2, FSHDIAG), FIOCLEX, (char *)0);
  1060.       (void) ioctl(OLDSTD = dcopy(SHIN, FOLDSTD), FIOCLEX, (char *)0);
  1061. + #else
  1062. +     SHIN = dcopy(0, FSHIN);
  1063. +     SHOUT = dcopy(1, FSHOUT);
  1064. +     SHDIAG = dcopy(2, FSHDIAG);
  1065. +     OLDSTD = dcopy(SHIN, FOLDSTD);
  1066. + #endif
  1067.       closem();
  1068.   }
  1069.   
  1070. ***************
  1071. *** 903,908
  1072.       closem();
  1073.   }
  1074.   
  1075.   #ifdef PROF
  1076.   done(i)
  1077.   #else
  1078.  
  1079. --- 1133,1541 -----
  1080.       closem();
  1081.   }
  1082.   
  1083. +   
  1084. + /*
  1085. +  * Karl Kleinpaste, 21oct1983.
  1086. +  * Added precmd(), which checks for the alias
  1087. +  * precmd in aliases.  If it's there, the alias
  1088. +  * is executed as a command.  This is done
  1089. +  * after mailchk() and just before print-
  1090. +  * ing the prompt.  Useful for things like printing
  1091. +  * one's current directory just before each command.
  1092. +  */
  1093. + precmd()
  1094. + {
  1095. +     int    omask;
  1096. +     omask = sighold (SIGINT);
  1097. +     if (precmd_active) {    /* an error must have been caught */
  1098. +         aliasrun (2, "unalias", "precmd");
  1099. +         printf ("Faulty alias 'precmd' removed.\n");
  1100. +         goto leave;
  1101. +     }
  1102. +     precmd_active++;
  1103. +     if (!whyles && adrof1 ("precmd", &aliases))
  1104. +         aliasrun (1, "precmd", (char *) 0);
  1105. + leave:
  1106. +     precmd_active = 0;
  1107. +     sigsetmask(omask);
  1108. + }
  1109. + /*
  1110. +  * Karl Kleinpaste, 18 Jan 1984.
  1111. +  * Added period_cmd(), which executes the alias "periodic" every
  1112. +  * $tperiod minutes.  Useful for occasional checking of msgs and such.
  1113. +  */
  1114. + period_cmd()
  1115. + {
  1116. +     register char *vp;
  1117. +     time_t t, interval;
  1118. +     int    omask;
  1119. +     omask = sighold (SIGINT);
  1120. +     if (periodic_active) {    /* an error must have been caught */
  1121. +         aliasrun (2, "unalias", "periodic");
  1122. +         printf ("Faulty alias 'periodic' removed.\n");
  1123. +         goto leave;
  1124. +     }
  1125. +     periodic_active++;
  1126. +     if (!whyles && adrof1 ("periodic", &aliases)) {
  1127. +         vp = value ("tperiod");
  1128. +         if (vp == (char *) 0)
  1129. +             return;
  1130. +         interval = getn (vp);
  1131. +         time (&t);
  1132. +         if (t - t_period >= interval * 60) {
  1133. +             t_period = t;
  1134. +             aliasrun (1, "periodic", (char *) 0);
  1135. +         }
  1136. +     }
  1137. + leave:
  1138. +     periodic_active = 0;
  1139. +     sigsetmask(omask);
  1140. + }
  1141. + /*
  1142. +  * Karl Kleinpaste, 21oct1983.
  1143. +  * Set up a one-word alias command, for use for special things.
  1144. +  * This code is based on the mainline of process().
  1145. +  */
  1146. + aliasrun (cnt, s1, s2)
  1147. +     int cnt;
  1148. +     char *s1, *s2;
  1149. + {
  1150. +     struct    wordent    w, *new1, *new2;    /* for holding alias name */
  1151. +     struct    command    *t = (struct command *) 0;
  1152. +     err = NOSTR;            /* don't repeatedly print err msg. */
  1153. +     w.word = "";
  1154. +     new1 = (struct wordent *) calloc (1, sizeof w);
  1155. +     new1->word = savestr (s1);
  1156. +     if (cnt == 1) {
  1157. +         /* build a lex list with one word. */
  1158. +         w.next = w.prev = new1;
  1159. +         new1->next = new1->prev = &w;
  1160. +     } else {
  1161. +         /* build a lex list with two words. */
  1162. +         new2 = (struct wordent *) calloc (1, sizeof w);
  1163. +         new2->word = savestr (s2);
  1164. +         w.next = new2->prev = new1;
  1165. +         new1->next = w.prev = new2;
  1166. +         new1->prev = new2->next = &w;
  1167. +     }
  1168. +     /* expand aliases like process() does. */
  1169. +     alias (&w);
  1170. +     /* build a syntax tree for the command. */
  1171. +     t = syntax (w.next, &w, 0);
  1172. +     if (err)
  1173. +         error (err);
  1174. +     /* execute the parse tree. */
  1175. +     execute (t, -1);
  1176. +     /* done. free the lex list and parse tree. */
  1177. +     freelex (&w), freesyn (t);
  1178. + }
  1179. + /*
  1180. +  * Karl Kleinpaste, 26 Jan 1984.
  1181. +  * Initialize the dummy tty list for login watch.
  1182. +  * This dummy list eliminates boundary conditions
  1183. +  * when doing pointer-chase searches.
  1184. +  */
  1185. + initwatch()
  1186. + {
  1187. +     wholist = (struct who *) calloc (1, sizeof *wholist);
  1188. +     wholist->w_next = (struct who *) calloc (1, sizeof *wholist);
  1189. +     wholist->w_next->w_prev = wholist;
  1190. +     strcpy (wholist->w_tty, "\01\01\01\01\01");
  1191. +     strcpy (wholist->w_next->w_tty, "~~~~~");
  1192. + #ifdef WHODEBUG
  1193. +     debugwholist ((struct who *) 0, (struct who *) 0);
  1194. + #endif WHODEBUG
  1195. + }
  1196. + /*
  1197. +  * Karl Kleinpaste, 26 Jan 1984.
  1198. +  * Watch /etc/utmp for login/logout changes.
  1199. +  */
  1200. + watch_login()
  1201. + {
  1202. +     int utmpfd, comparison, alldone, cnt;
  1203. +     struct utmp utmp;
  1204. +     struct who *wp, *wpnew;
  1205. +     struct varent *v;
  1206. +     char **vp, *cp;
  1207. +     time_t t, interval;
  1208. +     int    omask;
  1209. +     /* stop SIGINT, lest our login list get trashed. */
  1210. +     omask = sighold (SIGINT);
  1211. +     v = adrof ("watch");
  1212. +     if (v == (struct varent *) 0) {
  1213. +         sigsetmask(omask);
  1214. +         return;            /* no names to watch */
  1215. +     }
  1216. +     vp = v->vec;
  1217. +     cnt = blklen (vp);
  1218. +     if (cnt % 2) {            /* odd # args: 1st == # minutes. */
  1219. +         interval = (number (*vp)) ? getn (*vp++) : MAILINTVL;
  1220. +         cnt--;
  1221. +     }
  1222. +     time (&t);
  1223. +     if (t - watch_period < interval * 60) {
  1224. +         sigsetmask(omask);
  1225. +         return;            /* not long enough yet... */
  1226. +     }
  1227. +     watch_period = t;
  1228. +     if ((utmpfd = open ("/etc/utmp", 0)) < 0) {
  1229. +         printf ("/etc/utmp cannot be opened.  Please \"unset watch\".\n");
  1230. +         sigsetmask(omask);
  1231. +         return;
  1232. +     }
  1233. +     /*
  1234. +      * Read in the utmp file, sort the entries, and update existing
  1235. +      * entries or add new entries to the status list.
  1236. +      */
  1237. +     while (read (utmpfd, &utmp, sizeof utmp) == sizeof utmp) {
  1238. +         if (utmp.ut_name[0] == '\0' && utmp.ut_line[0] == '\0')
  1239. +             continue;    /* completely void entry */
  1240. +         wp = wholist;
  1241. +         while ((comparison = strncmp (wp->w_tty, utmp.ut_line, 8)) < 0)
  1242. +             wp = wp->w_next;    /* find that tty! */
  1243. +         if (comparison == 0) {        /* found the tty... */
  1244. +             if (utmp.ut_name[0] == '\0')
  1245. +                 wp->w_status = OFFLINE;
  1246. +             else            /* someone is logged in */
  1247. +                 if (strncmp (utmp.ut_name, wp->w_name, 8) == 0)
  1248. +                     wp->w_status = 0;    /* same guy */
  1249. +                 else {
  1250. +                     strncpy (wp->w_new, utmp.ut_name, 8);
  1251. +                     if (wp->w_name[0] == '\0')
  1252. +                         wp->w_status = ONLINE;
  1253. +                     else
  1254. +                         wp->w_status = CHANGED;
  1255. +                 }
  1256. +         } else {            /* new tty in utmp */
  1257. +             wpnew = (struct who *) calloc (1, sizeof *wpnew);
  1258. +             strncpy (wpnew->w_tty, utmp.ut_line, 8);
  1259. +             if (utmp.ut_name[0] == '\0')
  1260. +                 wpnew->w_status = OFFLINE;
  1261. +             else {
  1262. +                 strncpy (wpnew->w_new, utmp.ut_name, 8);
  1263. +                 wpnew->w_status = ONLINE;
  1264. +             }
  1265. + #ifdef WHODEBUG
  1266. +             debugwholist(wpnew, wp);
  1267. + #endif WHODEBUG
  1268. +             wpnew->w_next = wp;    /* link in a new 'who' */
  1269. +             wpnew->w_prev = wp->w_prev;
  1270. +             wpnew->w_prev->w_next = wpnew;
  1271. +             wp->w_prev = wpnew;    /* linked in now */
  1272. +         }
  1273. +     }
  1274. +     close (utmpfd);
  1275. +     /*
  1276. +      * The state of all logins is now known, so we can search
  1277. +      * the user's list of watchables to print the interesting ones.
  1278. +      */
  1279. +     for (alldone = 0; !alldone && *vp != (char *) 0 && **vp != '\0' &&
  1280. +             *(vp+1) != (char *) 0 && **(vp+1) != '\0';
  1281. +             vp += 2) {        /* args used in pairs... */
  1282. +         if (eq (*vp, "any") && eq (*(vp+1), "any"))
  1283. +             alldone++;
  1284. +         for (wp = wholist; wp != (struct who *) 0; wp = wp->w_next) {
  1285. +             if (wp->w_status & ANNOUNCE        ||
  1286. +                 (!eq (*vp, "any") && !eq (*vp, wp->w_name) &&
  1287. +                 !eq (*vp, wp->w_new))        ||
  1288. +                 (!eq (*(vp+1), wp->w_tty) && !eq (*(vp+1), "any")))
  1289. +                 continue;    /* entry doesn't qualify */
  1290. +                 /* already printed or not right one to print */
  1291. +             if ((wp->w_status & OFFLINE) &&
  1292. +                 (wp->w_name[0] != '\0')) {
  1293. +                 printf ("%s has logged off %s.\n",
  1294. +                     wp->w_name, wp->w_tty);
  1295. +                 wp->w_name[0] = '\0';
  1296. +                 wp->w_status |= ANNOUNCE;
  1297. +                 continue;
  1298. +             }
  1299. +             if (wp->w_status & ONLINE) {
  1300. +                 printf ("%s has logged on %s.\n",
  1301. +                     wp->w_new, wp->w_tty);
  1302. +                 strcpy (wp->w_name, wp->w_new);
  1303. +                 wp->w_status |= ANNOUNCE;
  1304. +                 continue;
  1305. +             }
  1306. +             if (wp->w_status & CHANGED) {
  1307. +                 printf ("%s has replaced %s on %s.\n",
  1308. +                     wp->w_new, wp->w_name, wp->w_tty);
  1309. +                 strcpy (wp->w_name, wp->w_new);
  1310. +                 wp->w_status |= ANNOUNCE;
  1311. +                 continue;
  1312. +             }
  1313. +         }
  1314. +     }
  1315. +     sigsetmask(omask);
  1316. + }
  1317. + #ifdef WHODEBUG
  1318. + debugwholist (new, wp)
  1319. + register struct who *new, *wp;
  1320. + {
  1321. +     register struct who *a;
  1322. +     a = wholist;
  1323. +     while (a != (struct who *) 0) {
  1324. +         printf ("%s/%s -> ", a->w_name, a->w_tty);
  1325. +         a = a->w_next;
  1326. +     }
  1327. +     printf ("NULL\n");
  1328. +     a = wholist;
  1329. +     printf ("backward: ");
  1330. +     while (a->w_next != (struct who *) 0)
  1331. +         a = a->w_next;
  1332. +     while (a != (struct who *) 0) {
  1333. +         printf ("%s/%s -> ", a->w_name, a->w_tty);
  1334. +         a = a->w_prev;
  1335. +     }
  1336. +     printf ("NULL\n");
  1337. +     if (new)
  1338. +         printf ("new: %s/%s\n", new->w_name, new->w_tty);
  1339. +     if (wp)
  1340. +         printf ("wp: %s/%s\n", wp->w_name, wp->w_tty);
  1341. + }
  1342. + #endif WHODEBUG
  1343. + /*
  1344. +  * kfk 21oct1983 -- add @ (time) and / ($cwd) in prompt.
  1345. +  * PWP 4/27/87 -- rearange for tcsh.
  1346. +  */
  1347. + printprompt ()
  1348. + {
  1349. +     register char *cp, *p, *z;
  1350. +     register char underlining = 0;
  1351. +     PromptBuf[0] = '\0';
  1352. +     p = PromptBuf;
  1353. +     if (whyles)
  1354. +     cp = value("prompt2");
  1355. +     else
  1356. +     cp = value("prompt");
  1357. +     for (; *cp; cp++) {
  1358. +     if (*cp == '%') {
  1359. +         cp++;
  1360. +         if (*cp == HIST || *cp == 'h') {
  1361. +         itoa(eventno + 1, buff);
  1362. +         for (z = buff; *z; z++)
  1363. +             *p++ = underlining | *z;
  1364. +         } else if (*cp == '@' || *cp == 't') {
  1365. +         struct tm *t;
  1366. +         long clock;
  1367. +         char ampm = 'a';
  1368. +         time (&clock);
  1369. +         t = localtime(&clock);
  1370. +         if (t->tm_hour >= 12) {
  1371. +             if (t->tm_hour > 12)
  1372. +             t->tm_hour -= 12;
  1373. +             ampm = 'p';
  1374. +         } else if (t->tm_hour == 0)
  1375. +             t->tm_hour = 12;
  1376. +         
  1377. +         itoa(t->tm_hour, buff);
  1378. +         *p++ = underlining | buff[0];
  1379. +         if (buff[1]) *p++ = underlining | buff[1];
  1380. +         *p++ = underlining | ':';
  1381. +         itoa(t->tm_min, buff);
  1382. +         if (buff[1]) {
  1383. +             *p++ = underlining | buff[0];
  1384. +             *p++ = underlining | buff[1];
  1385. +         } else {
  1386. +             *p++ = underlining | '0';
  1387. +             *p++ = underlining | buff[0];
  1388. +         }
  1389. +         *p++ = underlining | ampm;
  1390. +         *p++ = underlining | 'm';
  1391. +         } else if (*cp == 'M') {
  1392. +         for (z = getenv("HOST"); *z; z++)
  1393. +             *p++ = underlining | *z;
  1394. +         } else if (*cp == 'm') {
  1395. +         for (z = getenv("HOST"); *z && *z != '.'; z++)
  1396. +             *p++ = underlining | *z;
  1397. +         } else if (*cp == '/' || *cp == 'd') {
  1398. +         for (z = value("cwd"); *z; z++)
  1399. +             *p++ = underlining | *z;
  1400. +         } else if (*cp == '.' || *cp == 'c') {
  1401. +         strcpy (buff, value("cwd"));
  1402. +         if (!buff[1]) {    /* if CWD == / */
  1403. +             *p++ = underlining | buff[0];
  1404. +         } else {
  1405. +             if (strcmp(buff, value("home")) == 0) {
  1406. +             *p++ = underlining | '~';
  1407. +             } else {
  1408. +             for (z = buff; *z; z++) ; /* find the end */
  1409. +             while ((z > buff) && (*z != '/')) z--; /* back up */
  1410. +             if (*z == '/') z++;
  1411. +             while (*z)
  1412. +                 *p++ = underlining | *z++;
  1413. +             }
  1414. +         }
  1415. +         } else if (*cp == 'S' || *cp == 'U') { /* start standout */
  1416. +         underlining = 0200;
  1417. +         } else if (*cp == 's' || *cp == 'u') { /* end standout */
  1418. +         underlining = 0;
  1419. +         } else if (*cp == '%') {
  1420. +         *p++ = underlining | '%';
  1421. +         } else {
  1422. +         *p++ = underlining | '%';
  1423. +         *p++ = underlining | *cp;
  1424. +         }
  1425. +     } else {
  1426. +         *p++ = underlining | *cp;        /* normal character */
  1427. +     }
  1428. +     }
  1429. +     *p = '\0';
  1430. +     /*
  1431. +     cp = PromptBuf;
  1432. +     while (*cp)
  1433. +         putchar(*cp++ | QUOTE);
  1434. +     */
  1435. +     flush();
  1436. + }
  1437. + setalarm()
  1438. + {
  1439. +     struct varent *vp;
  1440. +     char *cp;
  1441. +     int alrm_time = 0;
  1442. +     long cl, sched_dif;
  1443. +     extern    struct    sched_event *sched_ptr;
  1444. +     if (vp = adrof("autologout"))
  1445. +     {
  1446. +         if (cp = vp->vec[0])
  1447. +             alrm_time = (atoi (cp) * 60);
  1448. +     }
  1449. +     if (sched_ptr) {
  1450. +         time(&cl);
  1451. +         sched_dif = sched_ptr->t_when - cl;
  1452. +         if ((alrm_time == 0) || (sched_dif < alrm_time))
  1453. +             alrm_time = ((int) sched_dif) + 1;
  1454. +     }
  1455. +     alarm (alrm_time);    /* Autologout ON */
  1456. + }
  1457.   #ifdef PROF
  1458.   done(i)
  1459.   #else
  1460. ***************
  1461. *** 915,938
  1462.       _exit(i);
  1463.   }
  1464.   
  1465. - printprompt()
  1466. - {
  1467. -     register char *cp;
  1468. -     if (!whyles) {
  1469. -         for (cp = value("prompt"); *cp; cp++)
  1470. -             if (*cp == HIST)
  1471. -                 printf("%d", eventno + 1);
  1472. -             else {
  1473. -                 if (*cp == '\\' && cp[1] == HIST)
  1474. -                     cp++;
  1475. -                 putchar(*cp | QUOTE);
  1476. -             }
  1477. -     } else
  1478. -         /* 
  1479. -          * Prompt for forward reading loop
  1480. -          * body content.
  1481. -          */
  1482. -         printf("? ");
  1483. -     flush();
  1484. - }
  1485.  
  1486. --- 1548,1550 -----
  1487.       _exit(i);
  1488.   }
  1489.   
  1490. *** sh.char.c    Sat Mar 29 07:37:20 1986
  1491. --- /usr/src/local/tcsh/sh.char.c    Mon Aug 17 23:30:38 1987
  1492. ***************
  1493. *** 60,66
  1494.       _META,        0,        _META,        _GLOB,
  1495.   
  1496.   /*    @        A        B        C    */
  1497. !     0,        _LET,        _LET,        _LET,
  1498.   
  1499.   /*    D        E        F        G    */
  1500.       _LET,        _LET,        _LET,        _LET,
  1501.  
  1502. --- 60,66 -----
  1503.       _META,        0,        _META,        _GLOB,
  1504.   
  1505.   /*    @        A        B        C    */
  1506. !     0,        _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_HEX|_UP,
  1507.   
  1508.   /*    D        E        F        G    */
  1509.       _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_UP,
  1510. ***************
  1511. *** 63,69
  1512.       0,        _LET,        _LET,        _LET,
  1513.   
  1514.   /*    D        E        F        G    */
  1515. !     _LET,        _LET,        _LET,        _LET,
  1516.   
  1517.   /*    H        I        J        K    */
  1518.       _LET,        _LET,        _LET,        _LET,
  1519.  
  1520. --- 63,69 -----
  1521.       0,        _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_HEX|_UP,
  1522.   
  1523.   /*    D        E        F        G    */
  1524. !     _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_UP,
  1525.   
  1526.   /*    H        I        J        K    */
  1527.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1528. ***************
  1529. *** 66,72
  1530.       _LET,        _LET,        _LET,        _LET,
  1531.   
  1532.   /*    H        I        J        K    */
  1533. !     _LET,        _LET,        _LET,        _LET,
  1534.   
  1535.   /*    L        M        N        O    */
  1536.       _LET,        _LET,        _LET,        _LET,
  1537.  
  1538. --- 66,72 -----
  1539.       _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_HEX|_UP,    _LET|_UP,
  1540.   
  1541.   /*    H        I        J        K    */
  1542. !     _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1543.   
  1544.   /*    L        M        N        O    */
  1545.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1546. ***************
  1547. *** 69,75
  1548.       _LET,        _LET,        _LET,        _LET,
  1549.   
  1550.   /*    L        M        N        O    */
  1551. !     _LET,        _LET,        _LET,        _LET,
  1552.   
  1553.   /*    P        Q        R        S    */
  1554.       _LET,        _LET,        _LET,        _LET,
  1555.  
  1556. --- 69,75 -----
  1557.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1558.   
  1559.   /*    L        M        N        O    */
  1560. !     _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1561.   
  1562.   /*    P        Q        R        S    */
  1563.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1564. ***************
  1565. *** 72,78
  1566.       _LET,        _LET,        _LET,        _LET,
  1567.   
  1568.   /*    P        Q        R        S    */
  1569. !     _LET,        _LET,        _LET,        _LET,
  1570.   
  1571.   /*    T        U        V        W    */
  1572.       _LET,        _LET,        _LET,        _LET,
  1573.  
  1574. --- 72,78 -----
  1575.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1576.   
  1577.   /*    P        Q        R        S    */
  1578. !     _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1579.   
  1580.   /*    T        U        V        W    */
  1581.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1582. ***************
  1583. *** 75,81
  1584.       _LET,        _LET,        _LET,        _LET,
  1585.   
  1586.   /*    T        U        V        W    */
  1587. !     _LET,        _LET,        _LET,        _LET,
  1588.   
  1589.   /*    X        Y        Z        [    */
  1590.       _LET,        _LET,        _LET,        _GLOB,
  1591.  
  1592. --- 75,81 -----
  1593.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1594.   
  1595.   /*    T        U        V        W    */
  1596. !     _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1597.   
  1598.   /*    X        Y        Z        [    */
  1599.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _GLOB,
  1600. ***************
  1601. *** 78,84
  1602.       _LET,        _LET,        _LET,        _LET,
  1603.   
  1604.   /*    X        Y        Z        [    */
  1605. !     _LET,        _LET,        _LET,        _GLOB,
  1606.   
  1607.   /*    \        ]        ^        _    */
  1608.       _ESC,        0,        0,        _LET,
  1609.  
  1610. --- 78,84 -----
  1611.       _LET|_UP,    _LET|_UP,    _LET|_UP,    _LET|_UP,
  1612.   
  1613.   /*    X        Y        Z        [    */
  1614. !     _LET|_UP,    _LET|_UP,    _LET|_UP,    _GLOB,
  1615.   
  1616.   /*    \        ]        ^        _    */
  1617.       _ESC,        0,        0,        _LET,
  1618. ***************
  1619. *** 84,90
  1620.       _ESC,        0,        0,        _LET,
  1621.   
  1622.   /*    `        a        b        c    */
  1623. !     _Q1|_GLOB,    _LET,        _LET,        _LET,
  1624.   
  1625.   /*    d        e        f        g    */
  1626.       _LET,        _LET,        _LET,        _LET,
  1627.  
  1628. --- 84,90 -----
  1629.       _ESC,        0,        0,        _LET,
  1630.   
  1631.   /*    `        a        b        c    */
  1632. !     _Q1|_GLOB,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,
  1633.   
  1634.   /*    d        e        f        g    */
  1635.       _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_LOW,
  1636. ***************
  1637. *** 87,93
  1638.       _Q1|_GLOB,    _LET,        _LET,        _LET,
  1639.   
  1640.   /*    d        e        f        g    */
  1641. !     _LET,        _LET,        _LET,        _LET,
  1642.   
  1643.   /*    h        i        j        k    */
  1644.       _LET,        _LET,        _LET,        _LET,
  1645.  
  1646. --- 87,93 -----
  1647.       _Q1|_GLOB,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,
  1648.   
  1649.   /*    d        e        f        g    */
  1650. !     _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_LOW,
  1651.   
  1652.   /*    h        i        j        k    */
  1653.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1654. ***************
  1655. *** 90,96
  1656.       _LET,        _LET,        _LET,        _LET,
  1657.   
  1658.   /*    h        i        j        k    */
  1659. !     _LET,        _LET,        _LET,        _LET,
  1660.   
  1661.   /*    l        m        n        o    */
  1662.       _LET,        _LET,        _LET,        _LET,
  1663.  
  1664. --- 90,96 -----
  1665.       _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_HEX|_LOW,    _LET|_LOW,
  1666.   
  1667.   /*    h        i        j        k    */
  1668. !     _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1669.   
  1670.   /*    l        m        n        o    */
  1671.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1672. ***************
  1673. *** 93,99
  1674.       _LET,        _LET,        _LET,        _LET,
  1675.   
  1676.   /*    l        m        n        o    */
  1677. !     _LET,        _LET,        _LET,        _LET,
  1678.   
  1679.   /*    p        q        r        s    */
  1680.       _LET,        _LET,        _LET,        _LET,
  1681.  
  1682. --- 93,99 -----
  1683.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1684.   
  1685.   /*    l        m        n        o    */
  1686. !     _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1687.   
  1688.   /*    p        q        r        s    */
  1689.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1690. ***************
  1691. *** 96,102
  1692.       _LET,        _LET,        _LET,        _LET,
  1693.   
  1694.   /*    p        q        r        s    */
  1695. !     _LET,        _LET,        _LET,        _LET,
  1696.   
  1697.   /*    t        u        v        w    */
  1698.       _LET,        _LET,        _LET,        _LET,
  1699.  
  1700. --- 96,102 -----
  1701.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1702.   
  1703.   /*    p        q        r        s    */
  1704. !     _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1705.   
  1706.   /*    t        u        v        w    */
  1707.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1708. ***************
  1709. *** 99,105
  1710.       _LET,        _LET,        _LET,        _LET,
  1711.   
  1712.   /*    t        u        v        w    */
  1713. !     _LET,        _LET,        _LET,        _LET,
  1714.   
  1715.   /*    x        y        z        {    */
  1716.       _LET,        _LET,        _LET,        _GLOB,
  1717.  
  1718. --- 99,105 -----
  1719.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1720.   
  1721.   /*    t        u        v        w    */
  1722. !     _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1723.   
  1724.   /*    x        y        z        {    */
  1725.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _GLOB,
  1726. ***************
  1727. *** 102,108
  1728.       _LET,        _LET,        _LET,        _LET,
  1729.   
  1730.   /*    x        y        z        {    */
  1731. !     _LET,        _LET,        _LET,        _GLOB,
  1732.   
  1733.   /*    |        }        ~        del    */
  1734.       _META,        0,        0,        0,
  1735.  
  1736. --- 102,108 -----
  1737.       _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _LET|_LOW,
  1738.   
  1739.   /*    x        y        z        {    */
  1740. !     _LET|_LOW,    _LET|_LOW,    _LET|_LOW,    _GLOB,
  1741.   
  1742.   /*    |        }        ~        del    */
  1743.       _META,        0,        0,        0,
  1744. *** sh.char.h    Sat Mar 29 07:37:14 1986
  1745. --- /usr/src/local/tcsh/sh.char.h    Mon Aug 17 23:28:06 1987
  1746. ***************
  1747. *** 24,29
  1748.   #define _DOL    0x80        /* $ */
  1749.   #define _DIG   0x100        /* 0-9 */
  1750.   #define _LET   0x200        /* a-z, A-Z, _ */
  1751.   
  1752.   #define cmap(c, bits)    (_cmap[(unsigned char)(c)] & (bits))
  1753.   
  1754.  
  1755. --- 24,32 -----
  1756.   #define _DOL    0x80        /* $ */
  1757.   #define _DIG   0x100        /* 0-9 */
  1758.   #define _LET   0x200        /* a-z, A-Z, _ */
  1759. + #define    _HEX   0x400        /* Hex digits */
  1760. + #define    _LOW   0x800        /* Lower case */
  1761. + #define    _UP   0x1000        /* Upper case */
  1762.   
  1763.   #define cmap(c, bits)    (_cmap[(unsigned char)(c)] & (bits))
  1764.   
  1765. ***************
  1766. *** 32,36
  1767.   #define isspnl(c)    cmap(c, _SP|_NL)
  1768.   #define ismeta(c)    cmap(c, _META)
  1769.   #define digit(c)    cmap(c, _DIG)
  1770.   #define letter(c)    cmap(c, _LET)
  1771.   #define alnum(c)    (digit(c) || letter(c))
  1772.  
  1773. --- 35,41 -----
  1774.   #define isspnl(c)    cmap(c, _SP|_NL)
  1775.   #define ismeta(c)    cmap(c, _META)
  1776.   #define digit(c)    cmap(c, _DIG)
  1777. + #define isdigit(c)    cmap(c, _DIG)
  1778.   #define letter(c)    cmap(c, _LET)
  1779.   #define isalpha(c)    cmap(c, _LET)
  1780.   #define islower(c)    cmap(c, _LOW)
  1781. ***************
  1782. *** 33,36
  1783.   #define ismeta(c)    cmap(c, _META)
  1784.   #define digit(c)    cmap(c, _DIG)
  1785.   #define letter(c)    cmap(c, _LET)
  1786.   #define alnum(c)    (digit(c) || letter(c))
  1787.  
  1788. --- 37,46 -----
  1789.   #define digit(c)    cmap(c, _DIG)
  1790.   #define isdigit(c)    cmap(c, _DIG)
  1791.   #define letter(c)    cmap(c, _LET)
  1792. + #define isalpha(c)    cmap(c, _LET)
  1793. + #define islower(c)    cmap(c, _LOW)
  1794. + #define isupper(c)    cmap(c, _UP)
  1795. + #define isxdigit(c)    cmap(c, _HEX)
  1796.   #define alnum(c)    (digit(c) || letter(c))
  1797.   #define toupper(c)    ((c)-'a'+'A')
  1798.   #define tolower(c)    ((c)-'A'+'a')
  1799. ***************
  1800. *** 34,36
  1801.   #define digit(c)    cmap(c, _DIG)
  1802.   #define letter(c)    cmap(c, _LET)
  1803.   #define alnum(c)    (digit(c) || letter(c))
  1804.  
  1805. --- 42,46 -----
  1806.   #define isupper(c)    cmap(c, _UP)
  1807.   #define isxdigit(c)    cmap(c, _HEX)
  1808.   #define alnum(c)    (digit(c) || letter(c))
  1809. + #define toupper(c)    ((c)-'a'+'A')
  1810. + #define tolower(c)    ((c)-'A'+'a')
  1811. *** sh.dir.c    Tue Jun 11 18:59:53 1985
  1812. --- /usr/src/local/tcsh/sh.dir.c    Mon Aug 17 19:58:48 1987
  1813. ***************
  1814. *** 230,235
  1815.       } else if (dp = dfind(*v)) {
  1816.           if (chdir(dp->di_name) < 0)
  1817.               Perror(dp->di_name);
  1818.       } else {
  1819.           register char *cp;
  1820.   
  1821.  
  1822. --- 230,240 -----
  1823.       } else if (dp = dfind(*v)) {
  1824.           if (chdir(dp->di_name) < 0)
  1825.               Perror(dp->di_name);
  1826. +         /*
  1827. +          * kfk - 10 Feb 1984 - added new "extraction style" pushd +n
  1828. +          */
  1829. +         if (adrof ("dextract"))
  1830. +             dextract (dp);
  1831.       } else {
  1832.           register char *cp;
  1833.   
  1834. ***************
  1835. *** 471,473
  1836.       if (printd)
  1837.           dodirs(fakev);
  1838.   }
  1839.  
  1840. --- 476,530 -----
  1841.       if (printd)
  1842.           dodirs(fakev);
  1843.   }
  1844. + /*
  1845. +  * getstakd - added by kfk 17 Jan 1984
  1846. +  * Support routine for the stack hack.  Finds nth directory in
  1847. +  * the directory stack, or finds last directory in stack.
  1848. +  */
  1849. + getstakd (s, cnt, callerr)
  1850. +     char *s;
  1851. +     int cnt, callerr;
  1852. + {
  1853. +     struct directory *dp;
  1854. +     dp = dcwd;
  1855. +     if (cnt < 0) {        /* < 0 ==> last dir requested. */
  1856. +         dp = dp->di_next;
  1857. +         if (dp == &dhead)
  1858. +             dp = dp->di_next;
  1859. +     } else {
  1860. +         while (cnt-- > 0) {
  1861. +             dp = dp->di_prev;
  1862. +             if (dp == &dhead)
  1863. +                 dp = dp->di_prev;
  1864. +             if (dp == dcwd) {
  1865. +                 if (callerr)
  1866. +                     error ("Not that many dir stack entries");
  1867. +                 else
  1868. +                     return;
  1869. +             }
  1870. +         }
  1871. +     }
  1872. +     strcpy (s, dp->di_name);
  1873. + }
  1874. + /*
  1875. +  * Karl Kleinpaste - 10 Feb 1984
  1876. +  * Added dextract(), which is used in pushd +n.
  1877. +  * Instead of just rotating the entire stack around, dextract()
  1878. +  * lets the user have the nth dir extracted from its current
  1879. +  * position, and pushes it onto the top.
  1880. +  */
  1881. + dextract(dp)
  1882. + struct directory *dp;
  1883. + {
  1884. +     if (dp == dcwd)
  1885. +         return;
  1886. +     dp->di_next->di_prev = dp->di_prev;
  1887. +     dp->di_prev->di_next = dp->di_next;
  1888. +     dp->di_next = dcwd->di_next;
  1889. +     dp->di_prev = dcwd;
  1890. +     dp->di_next->di_prev = dp;
  1891. +     dcwd->di_next = dp;
  1892. +  }
  1893. *** sh.err.c    Tue May 13 01:03:05 1986
  1894. --- /usr/src/local/tcsh/sh.err.c    Mon Aug 17 19:58:49 1987
  1895. ***************
  1896. *** 9,15
  1897.   #endif
  1898.   
  1899.   #include "sh.h"
  1900. ! #include <sys/ioctl.h>
  1901.   
  1902.   /*
  1903.    * C Shell
  1904.  
  1905. --- 9,15 -----
  1906.   #endif
  1907.   
  1908.   #include "sh.h"
  1909. ! /* #include <sys/ioctl.h> */
  1910.   
  1911.   /*
  1912.    * C Shell
  1913. ***************
  1914. *** 78,83
  1915.       btoeof();
  1916.   
  1917.       setq("status", onev, &shvhed);
  1918.       if (tpgrp > 0)
  1919.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
  1920.       reset();        /* Unwind */
  1921.  
  1922. --- 78,84 -----
  1923.       btoeof();
  1924.   
  1925.       setq("status", onev, &shvhed);
  1926. + #ifdef BSDJOBS
  1927.       if (tpgrp > 0)
  1928.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
  1929.   #endif
  1930. ***************
  1931. *** 80,85
  1932.       setq("status", onev, &shvhed);
  1933.       if (tpgrp > 0)
  1934.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
  1935.       reset();        /* Unwind */
  1936.   }
  1937.   
  1938.  
  1939. --- 81,87 -----
  1940.   #ifdef BSDJOBS
  1941.       if (tpgrp > 0)
  1942.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
  1943. + #endif
  1944.       reset();        /* Unwind */
  1945.   }
  1946.   
  1947. *** sh.exec.c    Thu Jun  6 13:15:32 1985
  1948. --- /usr/src/local/tcsh/sh.exec.c    Thu Sep 24 15:06:55 1987
  1949. ***************
  1950. *** 9,15
  1951.   #endif
  1952.   
  1953.   #include "sh.h"
  1954. ! #include <sys/dir.h>
  1955.   
  1956.   /*
  1957.    * C shell
  1958.  
  1959. --- 9,15 -----
  1960.   #endif
  1961.   
  1962.   #include "sh.h"
  1963. ! /* #include <sys/dir.h> */
  1964.   
  1965.   /*
  1966.    * C shell
  1967. ***************
  1968. *** 287,292
  1969.       char **pv;
  1970.       int hashval;
  1971.   
  1972.       havhash = 1;
  1973.       for (cnt = 0; cnt < sizeof xhash; cnt++)
  1974.           xhash[cnt] = 0;
  1975.  
  1976. --- 287,293 -----
  1977.       char **pv;
  1978.       int hashval;
  1979.   
  1980. +     tw_clear_comm_list();
  1981.       havhash = 1;
  1982.       for (cnt = 0; cnt < sizeof xhash; cnt++)
  1983.           xhash[cnt] = 0;
  1984. ***************
  1985. *** 298,303
  1986.           dirp = opendir(*pv);
  1987.           if (dirp == NULL)
  1988.               continue;
  1989.           if (fstat(dirp->dd_fd, &stb) < 0 || !isdir(stb)) {
  1990.               closedir(dirp);
  1991.               continue;
  1992.  
  1993. --- 299,305 -----
  1994.           dirp = opendir(*pv);
  1995.           if (dirp == NULL)
  1996.               continue;
  1997. + #ifdef COMMENT    /* this isn't needed.  opendir won't open non-dirs */
  1998.           if (fstat(dirp->dd_fd, &stb) < 0 || !isdir(stb)) {
  1999.               closedir(dirp);
  2000.               continue;
  2001. ***************
  2002. *** 302,307
  2003.               closedir(dirp);
  2004.               continue;
  2005.           }
  2006.           while ((dp = readdir(dirp)) != NULL) {
  2007.               if (dp->d_ino == 0)
  2008.                   continue;
  2009.  
  2010. --- 304,310 -----
  2011.               closedir(dirp);
  2012.               continue;
  2013.           }
  2014. + #endif
  2015.           while ((dp = readdir(dirp)) != NULL) {
  2016.               if (dp->d_ino == 0)
  2017.                   continue;
  2018. ***************
  2019. *** 331,336
  2020.               hits, misses, 100 * hits / (hits + misses));
  2021.   }
  2022.   #endif
  2023.   
  2024.   /*
  2025.    * Hash a command name.
  2026.  
  2027. --- 334,435 -----
  2028.               hits, misses, 100 * hits / (hits + misses));
  2029.   }
  2030.   #endif
  2031. + int
  2032. + iscommand(name)
  2033. +     char *name;
  2034. + {
  2035. +     char *sav;
  2036. +     register char *dp, **pv;
  2037. +     register struct varent *v;
  2038. +     bool slash = any('/', name);
  2039. +     int hashval, i;
  2040. +     v = adrof("path");
  2041. +     if (v == 0 || v->vec[0] == 0 || slash)
  2042. +         pv = justabs;
  2043. +     else
  2044. +         pv = v->vec;
  2045. +     sav = strspl("/", name);        /* / command name for postpending */
  2046. +     if (havhash)
  2047. +         hashval = hashname(name);
  2048. +     i = 0;
  2049. +     do {
  2050. +         if (!slash && pv[0][0] == '/' && havhash && (hashval & (1 << (i % 8))) == 0)
  2051. +             goto cont;
  2052. +         if (pv[0][0] == 0 || eq(pv[0], ".")) {    /* don't make ./xxx */
  2053. +             if (access(name, 1) == 0) {
  2054. +                 xfree(sav);
  2055. +                 return i+1;
  2056. +             }
  2057. +         } else {
  2058. +             dp = strspl(*pv, sav);
  2059. +             if (access(dp, 1) == 0) {
  2060. +                 xfree(sav);
  2061. +                 xfree(dp);
  2062. +                 return i+1;
  2063. +             }
  2064. +             xfree(dp);
  2065. +         }
  2066. + cont:
  2067. +         pv++;
  2068. +         i++;
  2069. +     } while (*pv);
  2070. +     xfree(sav);
  2071. +     return 0;
  2072. + }
  2073. + tellmewhat(lex)
  2074. +     struct wordent *lex;
  2075. + {
  2076. +     register char *cp;
  2077. +     register int i;
  2078. +     register struct biltins *bptr;
  2079. +     register struct wordent *sp = lex->next;
  2080. +     for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
  2081. + #ifdef    OUTDEF
  2082. +     for (bptr = bfunc; cp = bptr->bname; bptr++) {
  2083. + #endif
  2084. +     if (strcmp(sp->word, bptr->bname) == 0) {
  2085. +         prlex(lex);
  2086. +         printf("%s: is built in.\n", sp->word);
  2087. +         flush();
  2088. +         return;
  2089. +     }
  2090. +     }
  2091. +     while (*(sp->word) & 0200) (sp->word)++;
  2092. +     if (i = iscommand(strip(sp->word))) {
  2093. +     char *s1;
  2094. +     register char **pv;
  2095. +     register struct varent *v;
  2096. +     bool slash = any('/', sp->word);
  2097. +     v = adrof("path");
  2098. +     if (v == 0 || v->vec[0] == 0 || slash)
  2099. +         pv = justabs;
  2100. +     else
  2101. +         pv = v->vec;
  2102. +     while (--i) pv++;
  2103. +     if (pv[0][0] == 0 || eq(pv[0], ".")) {
  2104. +         prlex(lex);
  2105. +         return;
  2106. +     }
  2107. +     s1 = strspl(*pv, "/");
  2108. +     sp->word = strspl(s1, sp->word);
  2109. +     xfree(s1);
  2110. +     prlex(lex);
  2111. +     xfree(sp->word);
  2112. +     sp->word = (char *)0;
  2113. +     } else {
  2114. +     prlex(lex);
  2115. +     printf("%s: Command not found.\n", sp->word);
  2116. +     flush();
  2117. +     }
  2118. + }
  2119.   
  2120.   /*
  2121.    * Hash a command name.
  2122. *** sh.file.c    Sun May 18 23:01:20 1986
  2123. --- /usr/src/local/tcsh/sh.file.c    Mon Aug 17 19:21:52 1987
  2124. ***************
  2125. *** 174,179
  2126.       return (' ');
  2127.   }
  2128.   
  2129.   static struct winsize win;
  2130.   
  2131.   /*
  2132.  
  2133. --- 174,188 -----
  2134.       return (' ');
  2135.   }
  2136.   
  2137. + #ifndef    BSD4_3
  2138. + struct    winsize {
  2139. +     unsigned short    ws_row;
  2140. +     unsigned short    ws_col;
  2141. +     unsigned short    ws_xpixel;
  2142. +     unsigned short    ws_ypixel;
  2143. + };
  2144. + #endif
  2145.   static struct winsize win;
  2146.   
  2147.   /*
  2148. ***************
  2149. *** 185,190
  2150.   {
  2151.       register int i, rows, r, c, maxwidth = 0, columns;
  2152.   
  2153.       if (ioctl(SHOUT, TIOCGWINSZ, (char *)&win) < 0 || win.ws_col == 0)
  2154.           win.ws_col = 80;
  2155.       for (i = 0; i < count; i++)
  2156.  
  2157. --- 194,200 -----
  2158.   {
  2159.       register int i, rows, r, c, maxwidth = 0, columns;
  2160.   
  2161. + #ifdef    BSD4_3
  2162.       if (ioctl(SHOUT, TIOCGWINSZ, (char *)&win) < 0 || win.ws_col == 0)
  2163.   #endif
  2164.           win.ws_col = 80;
  2165. ***************
  2166. *** 186,191
  2167.       register int i, rows, r, c, maxwidth = 0, columns;
  2168.   
  2169.       if (ioctl(SHOUT, TIOCGWINSZ, (char *)&win) < 0 || win.ws_col == 0)
  2170.           win.ws_col = 80;
  2171.       for (i = 0; i < count; i++)
  2172.           maxwidth = maxwidth > (r = strlen(items[i])) ? maxwidth : r;
  2173.  
  2174. --- 196,202 -----
  2175.   
  2176.   #ifdef    BSD4_3
  2177.       if (ioctl(SHOUT, TIOCGWINSZ, (char *)&win) < 0 || win.ws_col == 0)
  2178. + #endif
  2179.           win.ws_col = 80;
  2180.       for (i = 0; i < count; i++)
  2181.           maxwidth = maxwidth > (r = strlen(items[i])) ? maxwidth : r;
  2182. *** sh.func.c    Tue May 13 01:03:48 1986
  2183. --- /usr/src/local/tcsh/sh.func.c    Thu Sep 24 15:08:48 1987
  2184. ***************
  2185. *** 9,15
  2186.   #endif
  2187.   
  2188.   #include "sh.h"
  2189. ! #include <sys/ioctl.h>
  2190.   
  2191.   /*
  2192.    * C shell
  2193.  
  2194. --- 9,15 -----
  2195.   #endif
  2196.   
  2197.   #include "sh.h"
  2198. ! /* #include <sys/ioctl.h> */
  2199.   
  2200.   /*
  2201.    * C shell
  2202. ***************
  2203. *** 175,181
  2204.       islogin();
  2205.       rechist();
  2206.       (void) signal(SIGTERM, parterm);
  2207. !     execl("/bin/login", "login", v[1], 0);
  2208.       untty();
  2209.       exit(1);
  2210.   }
  2211.  
  2212. --- 175,181 -----
  2213.       islogin();
  2214.       rechist();
  2215.       (void) signal(SIGTERM, parterm);
  2216. !     execl("/bin/login", "login", v[1], (char *) 0);
  2217.       untty();
  2218.       exit(1);
  2219.   }
  2220. ***************
  2221. *** 180,185
  2222.       exit(1);
  2223.   }
  2224.   
  2225.   #ifdef NEWGRP
  2226.   donewgrp(v)
  2227.       char **v;
  2228.  
  2229. --- 180,204 -----
  2230.       exit(1);
  2231.   }
  2232.   
  2233. + dolog()
  2234. + {
  2235. +     extern struct who *wholist;
  2236. +     extern time_t watch_period;
  2237. +     struct who *wp;
  2238. +     struct varent *v;
  2239. +     if ((v = adrof ("watch")) == (struct varent *) 0)
  2240. +         error ("No $watch variable set");
  2241. +     blkpr (v->vec);
  2242. +     printf ("\n");
  2243. +     watch_period = 0;
  2244. +     wp = wholist;
  2245. +     while (wp != (struct who *) 0) {
  2246. +         wp->w_name[0] = '\0';
  2247. +         wp = wp->w_next;
  2248. +     }
  2249. + }
  2250.   #ifdef NEWGRP
  2251.   donewgrp(v)
  2252.       char **v;
  2253. ***************
  2254. *** 188,195
  2255.       if (chkstop == 0 && setintr)
  2256.           panystop(0);
  2257.       (void) signal(SIGTERM, parterm);
  2258. !     execl("/bin/newgrp", "newgrp", v[1], 0);
  2259. !     execl("/usr/bin/newgrp", "newgrp", v[1], 0);
  2260.       untty();
  2261.       exit(1);
  2262.   }
  2263.  
  2264. --- 207,214 -----
  2265.       if (chkstop == 0 && setintr)
  2266.           panystop(0);
  2267.       (void) signal(SIGTERM, parterm);
  2268. !     execl("/bin/newgrp", "newgrp", v[1], (char *) 0);
  2269. !     execl("/usr/bin/newgrp", "newgrp", v[1], (char *) 0);
  2270.       untty();
  2271.       exit(1);
  2272.   }
  2273. ***************
  2274. *** 532,538
  2275.           bseek((off_t)0);
  2276.       do {
  2277.           if (intty && fseekp == feobp)
  2278. !             printf("? "), flush();
  2279.           aword[0] = 0;
  2280.           (void) getword(aword);
  2281.           switch (srchx(aword)) {
  2282.  
  2283. --- 551,557 -----
  2284.           bseek((off_t)0);
  2285.       do {
  2286.           if (intty && fseekp == feobp)
  2287. !             printprompt(); /* printf("? "), flush(); */
  2288.           aword[0] = 0;
  2289.           (void) getword(aword);
  2290.           switch (srchx(aword)) {
  2291. ***************
  2292. *** 866,872
  2293.       (void) umask(i);
  2294.   }
  2295.   
  2296.   struct limits {
  2297.       int    limconst;
  2298.       char    *limname;
  2299.  
  2300. --- 885,891 -----
  2301.       (void) umask(i);
  2302.   }
  2303.   
  2304. ! #ifndef OREO
  2305.   struct limits {
  2306.       int    limconst;
  2307.       char    *limname;
  2308. ***************
  2309. *** 1074,1079
  2310.       }
  2311.       return (0);
  2312.   }
  2313.   
  2314.   dosuspend()
  2315.   {
  2316.  
  2317. --- 1093,1099 -----
  2318.       }
  2319.       return (0);
  2320.   }
  2321. + #endif OREO
  2322.   
  2323.   #ifdef SVID
  2324.   extern struct termio termiob;
  2325. ***************
  2326. *** 1075,1080
  2327.       return (0);
  2328.   }
  2329.   
  2330.   dosuspend()
  2331.   {
  2332.       int ldisc, ctpgrp;
  2333.  
  2334. --- 1095,1104 -----
  2335.   }
  2336.   #endif OREO
  2337.   
  2338. + #ifdef SVID
  2339. + extern struct termio termiob;
  2340. + #endif SVID
  2341.   dosuspend()
  2342.   {
  2343.       int ldisc, ctpgrp;
  2344. ***************
  2345. *** 1087,1092
  2346.       (void) kill(0, SIGTSTP);
  2347.       /* the shell stops here */
  2348.       (void) signal(SIGTSTP, old);
  2349.       if (tpgrp != -1) {
  2350.   retry:
  2351.           (void) ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp);
  2352.  
  2353. --- 1111,1117 -----
  2354.       (void) kill(0, SIGTSTP);
  2355.       /* the shell stops here */
  2356.       (void) signal(SIGTSTP, old);
  2357. + #ifdef BSDJOBS
  2358.       if (tpgrp != -1) {
  2359.   retry:
  2360.           (void) ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp);
  2361. ***************
  2362. *** 1099,1104
  2363.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&shpgrp);
  2364.           (void) setpgrp(0, shpgrp);
  2365.       }
  2366.       (void) ioctl(FSHTTY, TIOCGETD, (char *)&oldisc);
  2367.       if (oldisc != NTTYDISC) {
  2368.           printf("Switching to new tty driver...\n");
  2369.  
  2370. --- 1124,1141 -----
  2371.           (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&shpgrp);
  2372.           (void) setpgrp(0, shpgrp);
  2373.       }
  2374. + #endif BSDJOBS
  2375. + #ifdef SVID
  2376. +     (void) ioctl(FSHTTY, TCGETA, &termiob);
  2377. +     if (termiob.c_cc[VSWTCH] != CSWTCH) {
  2378. + #ifdef DEBUG
  2379. +         printf ("Setting ^Z...\n");
  2380. + #endif DEBUG
  2381. +         termiob.c_cc[VSWTCH] = CSWTCH;
  2382. +         (void) ioctl(FSHTTY, TCSETA, &termiob);
  2383. +     }
  2384. + #else SVID
  2385.       (void) ioctl(FSHTTY, TIOCGETD, (char *)&oldisc);
  2386.       if (oldisc != NTTYDISC) {
  2387.           printf("Switching to new tty driver...\n");
  2388. ***************
  2389. *** 1105,1110
  2390.           ldisc = NTTYDISC;
  2391.           (void) ioctl(FSHTTY, TIOCSETD, (char *)&ldisc);
  2392.       }
  2393.   }
  2394.   
  2395.   doeval(v)
  2396.  
  2397. --- 1142,1148 -----
  2398.           ldisc = NTTYDISC;
  2399.           (void) ioctl(FSHTTY, TIOCSETD, (char *)&ldisc);
  2400.       }
  2401. + #endif SVID
  2402.   }
  2403.   
  2404.   doeval(v)
  2405. ***************
  2406. *** 1146,1148
  2407.       if (reenter >= 2)
  2408.           error(NOSTR);
  2409.   }
  2410.  
  2411. --- 1184,1366 -----
  2412.       if (reenter >= 2)
  2413.           error(NOSTR);
  2414.   }
  2415. + /*
  2416. +  * kfk - added scheduled event functions
  2417. +  */
  2418. + struct sched_event *sched_ptr;
  2419. + dosched(v)
  2420. +     register char **v;
  2421. + {
  2422. +     register struct sched_event *tp, *tp1, *tp2;
  2423. +     long cur_time;
  2424. +     int count, hours, minutes, dif_hour, dif_min;
  2425. +     char *cp;
  2426. +     bool relative;        /* time specified as +hh:mm */
  2427. +     struct tm *ltp;
  2428. +     char *timeline;
  2429. +     char *ctime();
  2430. +     v++;
  2431. +     cp = *v++;
  2432. +     if (cp == (char *) 0) {
  2433. +         /* print list of scheduled events */
  2434. +         for (count = 1, tp = sched_ptr; tp; count++, tp = tp->t_next) {
  2435. +             timeline = ctime(&tp->t_when);
  2436. +             timeline[16] = '\0';
  2437. +             printf ("%6d\t%s\t", count, timeline);
  2438. +             blkpr (tp->t_lex);
  2439. +             printf ("\n");
  2440. +         }
  2441. +         return;
  2442. +     }
  2443. +     if (*cp == '-') {
  2444. +         /* remove item from list */
  2445. +         if (!sched_ptr)
  2446. +             error ("No scheduled events");
  2447. +         if (*v)
  2448. +             error ("Too many args for 'sched -<item#>'");
  2449. +         count = atoi (++cp);
  2450. +         if (count <= 0)
  2451. +             error ("Usage to delete: sched -<item#>");
  2452. +         tp = sched_ptr;
  2453. +         tp1 = 0;
  2454. +         while (--count) {
  2455. +             if (tp->t_next == 0)
  2456. +                 break;
  2457. +             else {
  2458. +                 tp1 = tp;
  2459. +                 tp = tp->t_next;
  2460. +             }
  2461. +         }
  2462. +         if (count)
  2463. +             error ("Not that many scheduled events");
  2464. +         if (tp1 == 0)
  2465. +             sched_ptr = tp->t_next;
  2466. +         else
  2467. +             tp1->t_next = tp->t_next;
  2468. +         blkfree (tp->t_lex);
  2469. +         xfree ((char *) tp);
  2470. +         return;
  2471. +     }
  2472. +     /* else, add an item to the list */
  2473. +     if (!*v)
  2474. +         error ("No command to run");
  2475. +     relative = 0;
  2476. +     if (!digit(*cp)) {        /* not abs. time */
  2477. +         if (*cp != '+')
  2478. +             error ("Usage: sched [+]hh:mm <command>");
  2479. +         cp++, relative++;
  2480. +     }
  2481. +     minutes = 0;
  2482. +     hours = atoi(cp);
  2483. +     while (*cp && *cp != ':' && *cp != 'a' && *cp != 'p')
  2484. +         cp++;
  2485. +     if (*cp && *cp == ':')
  2486. +         minutes = atoi(++cp);
  2487. +     if ((hours < 0) || (minutes < 0) ||
  2488. +         (hours > 23) || (minutes > 59))
  2489. +         error ("Invalid time for event");
  2490. +     while (*cp && *cp != 'p' && *cp != 'a')
  2491. +         cp++;
  2492. +     if (*cp && relative)
  2493. +         error ("Relative time inconsistent with am/pm");
  2494. +     if (*cp == 'p')
  2495. +         hours += 12;
  2496. +     time(&cur_time);
  2497. +     ltp = localtime(&cur_time);
  2498. +     if (relative) {
  2499. +         dif_hour = hours;
  2500. +         dif_min = minutes;
  2501. +     } else {
  2502. +         if ((dif_hour = hours - ltp->tm_hour) < 0)
  2503. +             dif_hour += 24;
  2504. +         if ((dif_min = minutes - ltp->tm_min) < 0) {
  2505. +             dif_min += 60;
  2506. +             if ((--dif_hour) < 0)
  2507. +                 dif_hour = 23;
  2508. +         }
  2509. +     }
  2510. +     tp = (struct sched_event *) calloc (1, sizeof *tp);
  2511. +     tp->t_when = cur_time - ltp->tm_sec + dif_hour*3600L + dif_min*60L;
  2512. +             /* use of tm_sec: get to beginning of minute. */
  2513. +     if (!sched_ptr || tp->t_when < sched_ptr->t_when) {
  2514. +         tp->t_next = sched_ptr;
  2515. +         sched_ptr = tp;
  2516. +     } else {
  2517. +         tp1 = sched_ptr->t_next;
  2518. +         tp2 = sched_ptr;
  2519. +         while (tp1 && tp->t_when >= tp1->t_when) {
  2520. +             tp2 = tp1;
  2521. +             tp1 = tp1->t_next;
  2522. +         }
  2523. +         tp->t_next = tp1;
  2524. +         tp2->t_next = tp;
  2525. +     }
  2526. +     tp->t_lex = saveblk(v);
  2527. + }
  2528. + /*
  2529. +  * Execute scheduled events
  2530. +  */
  2531. + sched_run()
  2532. + {
  2533. +     long    cur_time;
  2534. +     register struct sched_event *tp, *tp1;
  2535. +     struct wordent cmd, *nextword, *lastword;
  2536. +     struct command *t = (struct command *) 0;
  2537. +     char **v, *cp;
  2538. +     extern int GettingInput;
  2539. +     int    omask;
  2540. +     omask = sighold (SIGINT);
  2541. +        
  2542. +         if (GettingInput)
  2543. +         Cookedmode();
  2544. +     time(&cur_time);
  2545. +     tp = sched_ptr;
  2546. +     while (tp && tp->t_when < cur_time) {
  2547. +         err = NOSTR;
  2548. +         cmd.word = "";
  2549. +         lastword = &cmd;
  2550. +         v = tp->t_lex;
  2551. +         for (cp = *v; cp; cp = *++v) {
  2552. +             nextword = (struct wordent *) calloc (1, sizeof cmd);
  2553. +             nextword->word = savestr (cp);
  2554. +             lastword->next = nextword;
  2555. +             nextword->prev = lastword;
  2556. +             lastword = nextword;
  2557. +         }
  2558. +         lastword->next = &cmd;
  2559. +         cmd.prev = lastword;
  2560. +         tp1 = tp;
  2561. +         sched_ptr = tp = tp1->t_next;    /* looping termination cond: */
  2562. +         blkfree (tp1->t_lex);        /* straighten out in case of */
  2563. +         xfree ((char *) tp1);        /* command blow-up. */
  2564. +         /* expand aliases like process() does. */
  2565. +         alias (&cmd);
  2566. +         /* build a syntax tree for the command. */
  2567. +         t = syntax (cmd.next, &cmd, 0);
  2568. +         if (err)
  2569. +             error (err);
  2570. +         /* execute the parse tree. */
  2571. +         execute (t, -1);
  2572. +         /* done. free the lex list and parse tree. */
  2573. +         freelex (&cmd), freesyn (t);
  2574. +     }
  2575. +         if (GettingInput) {    /* PWP */
  2576. +         Rawmode();
  2577. +         ClearLines();    /* do a real refresh since something may */
  2578. +         ClearDisp();    /* have printed to the screen */
  2579. +         Refresh();
  2580. +     }
  2581. +     sigsetmask(omask);
  2582. + }
  2583. + /* kfk - end change */
  2584. SHAR_EOF
  2585. fi
  2586. exit 0
  2587. #    End of shell archive
  2588.